package com.gitee.wsl.common.ui.base

import androidx.compose.ui.unit.dp
import com.gitee.wsl.common.ui.api.PaddingContainsPoint
import com.gitee.wsl.mathematics.geometry.shape.Rectangle

/**
 * Special immutable class to hold padding information
 */
open class Padding(open var left: Float=0f,open var top: Float=0f,open var right: Float=0f,open var bottom: Float=0f):
    PaddingContainsPoint {

    val horizontalPadding:Float get() = left + right

    val verticalPadding:Float get() = top + bottom

    override fun contains(x: Float, y: Float, innerRectangle: Rectangle): Boolean {
        val leftDis = x-innerRectangle.left
        val rightDis = x-innerRectangle.right
        val topDis = y - innerRectangle.top
        val bottomDis = y - innerRectangle.bottom
        if(leftDis>0 && leftDis <left || rightDis > 0 && rightDis<right)
            if(topDis >0 && topDis < top || bottomDis > 0 && bottomDis < bottom)
                return true
        return false
    }

    /**
     * Updates the horizontal and vertical padding.
     */
     fun setPadding(
        horizontal: Float = 0f,
        vertical: Float = 0f,
    ) {
        setPadding(horizontal, vertical, horizontal, vertical)
    }

    fun setPadding(left: Float , top: Float , right:Float, bottom:Float) {
        this.left = left
        this.top = top
        this.right = right
        this.bottom = bottom
    }

    override fun toString(): String {
        return "Padding{" +
                "left=" + left +
                ", top=" + top +
                ", right=" + right +
                ", bottom=" + bottom +
                '}'
    }

    companion object {
        fun all(value: Float): Padding {
            return Padding(value, value, value, value)
        }

        fun symmetric(vertical: Float, horizontal: Float): Padding {
            return Padding(horizontal, vertical, horizontal, vertical)
        }

        /**
         * @since 4.5.0
         */
        fun of(left: Float, top: Float, right: Float, bottom: Float): Padding {
            return Padding(left, top, right, bottom)
        }


        val none by lazy{ Padding(0f, 0f, 0f, 0f)}
        val default by lazy{ Padding(5f, 5f, 5f, 5f)}
        val medium by lazy{ Padding(10f, 10f, 10f, 10f)}
        val wide by lazy{ Padding(25f, 10f, 25f, 10f)}
        val wideRight by lazy{ Padding(10f, 10f, 25f, 10f)}

        val ExtraTiny = 2.dp
        val Tiny = 4.dp
        val ExtraSmall = 8.dp
        val Small = 12.dp
        val Default = 16.dp
        val Large = 24.dp
        val ExtraLarge = 32.dp
    }
}

fun Padding.add(other: Padding): Padding {
    this.left += other.left
    this.top += other.top
    this.right+=other.right
    this.bottom+=other.bottom
    return this
}

operator fun Padding.plusAssign(other: Padding) {
    val newPadding=Padding()
    newPadding.add(other)
}

operator fun Padding.plus(factor: Float): Padding {
    return Padding(
        this.left + factor,
        this.top + factor,
        this.right +factor,
        this.bottom +factor)
}

operator fun Padding.plus(other: Padding): Padding {
    return  Padding(
        this.left + other.left,
        this.top + other.top,
        this.right+other.right,
        this.bottom+other.bottom)
}

/**
 * Indicates a class that has a width and a height. Adds a size property to
 * set and get width and height in a single line.
 */
interface HasPadding {

    var padding:Padding

}